package final

import (
	"context"
	"net/http"
	"sync"
)

// Task 定义任务接口
type Task interface {
	Execute(context.Context, *http.Client) (interface{}, error)
}

// Result 定义结果结构
type Result struct {
	Source interface{}
	Data   interface{}
	Err    error
}

// Base 负责管理worker池
type Worker struct {
	concurrency int
	tasks       chan Task
	results     chan Result
	wg          sync.WaitGroup
	httpPool    *HttpPool
}

// NewBase 创建一个新的Base实例
func NewWorker(concurrency, chan_length int, httpPool *HttpPool) *Worker {
	work := &Worker{
		concurrency: concurrency,
		tasks:       make(chan Task, chan_length),
		results:     make(chan Result, chan_length),
		httpPool:    httpPool,
	}
	work.Start()
	return work
}

func NewWorkers(num, concurrency, chan_length int, httpPool *HttpPool) []*Worker {
	workers := make([]*Worker, 0, num)
	for i := 0; i < num; i++ {
		workers = append(workers, NewWorker(concurrency, chan_length, httpPool))
	}
	return workers
}

// Start 启动worker池
func (b *Worker) Start() {
	for i := 0; i < b.concurrency; i++ {
		b.wg.Add(1)
		go func(r chan Result) {
			defer b.wg.Done()
			for task := range b.tasks {
				ctx := context.TODO()
				func(ctx1 context.Context) {
					var err error
					var httpClient *http.Client
					if b.httpPool != nil {
						httpClient = b.httpPool.Get(ctx1)
						defer b.httpPool.Release(ctx1, httpClient)
					}
					result := Result{
						Source: task,
					}
					if result.Data, err = task.Execute(ctx1, httpClient); err != nil {
						result.Err = err
					}
					r <- result
				}(ctx)
			}
		}(b.results)
	}
}

// Submit 提交任务到队列
func (b *Worker) Submit(tasks ...Task) {
	for _, task := range tasks {
		b.tasks <- task
	}
}

// Results 返回结果通道
func (b *Worker) Results() <-chan Result {
	return b.results
}

// Stop 停止worker池
func (b *Worker) Stop() {
	close(b.tasks)
	b.wg.Wait()
	close(b.results)
}
